<template>
	<view class="container" :style="{'background-color':`${bgColor}`}">
		<view class="container-left" :style="{'background-color':`${bgColor}`}">
			<view class="ele-container">
				<canvas class="nnCanvas" canvas-id="nnCanvas"
					:style="{height:`${canvasHeight}px`,width:`${canvasWidth}px`}"></canvas>
			</view>
		</view>
		
		<view class="container-right">
			<view>
				<view class="">画布背景颜色
					<el-color-picker v-model="bgColor"></el-color-picker>
				</view>
				
				<view class="">文本<el-input v-model="text" @change="handleChangeText" placeholder="请输入内容" size="mini" type="textarea"></el-input>
				</view>
				<view class="">字号<el-input-number v-model="fontSize" @change="handleUpdataCanvas" :min="20" :max="300" label="字号" step-strictly size="mini"></el-input-number>
				</view>
				<view class="">行高<el-input-number v-model="lineHeight" @change="handleUpdataCanvas" :min="8" :max="50" label="行高" step-strictly size="mini"></el-input-number>
				</view>
				<view class="">字距<el-input-number v-model="letterSpacing" @change="handleUpdataCanvas" :min="0" :max="30" label="字距" step-strictly size="mini"></el-input-number>
				</view>
				<view class="">颜色
					<el-color-picker v-model="fontColor" @change="handleUpdataCanvas" show-alpha></el-color-picker>
				</view>
				<view class="">加粗
					<el-checkbox v-model="isBold" label="加粗" border size="mini" @change="handleUpdataCanvas"></el-checkbox>
				</view>
				<view class="">描边
					<el-checkbox v-model="isStroke" label="描边" border size="mini" @change="handleUpdataCanvas"></el-checkbox>
				</view>
				<view class="" v-if="isStroke">描边宽度
					<el-input-number v-model="strokeWidth" @change="handleUpdataCanvas" :min="1" :max="5" label="描边宽度" step-strictly size="mini"></el-input-number>
				</view>
				<view class="" v-if="isStroke">描边颜色
					<el-color-picker v-model="strokeColor" @change="handleUpdataCanvas" show-alpha></el-color-picker>
				</view>
				<view class="" v-if="isStroke">是否镂空
					<el-checkbox v-model="isHollow" label="镂空" border size="mini" @change="handleUpdataCanvas"></el-checkbox>
				</view>
				
				
				<button @click="onDownload">下载</button>
				<button @click="chooseFile">选择文件</button>
			</view>
		</view>
		
		
		
	</view>
</template>

<script>
	import {
		saveAs
	} from 'file-saver';
	export default {
		data() {
			return {
				canvasWidth: 512,
				canvasHeight: 512,
				ctx: null,
				fontSize: 30,
				/** 行高 */
				lineHeight: 5,
				letterSpacing: 0,
				/** 需要保存的数据 */
				fontDataList: [],
				text:'+-=这是一段很0123456789长的qwertyuiopasdfghjklzxcvbnm文本 ',
				fontColor: '#000',
				bgColor: '#afafaf',
				isBold:false,
				isStroke:false,
				strokeWidth:1,
				strokeColor:'#ff0a0a',
				isHollow:false,
				familyPath:'Arial'
			}
		},
		mounted() {
			// 微信不使用 canvas 2d
			// let ctx = uni.createCanvasContext('nnCanvas', this);
				// ctx.setTextBaseline('middle');
			this.handleDrawText();
		},
		onLoad() {
			this.ctx = uni.createCanvasContext('nnCanvas', this);
		},
		methods: {
			handleChangeFontSize(value){
				this.handleDrawText()
				setTimeout(() => {
					this.handleDrawText();
				}, 10)
			},
			chooseFile(){
				var _this = this;
				uni.chooseFile({
				  count: 1,
				  extension:['.ttf'],
					success: function (res) {
						_this.familyPath = res.tempFilePaths[0];
						uni.loadFontFace({
						  family: 'myFamily',
						  source: `url(${_this.familyPath})`,
						  success() {
							  console.error('success')
								_this.handleDrawText()
								setTimeout(() => {
									_this.handleDrawText();
								}, 10)
						  }
						})
						
					}
				});
			},
			handleDrawText() {
				// this.ctx.clearRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height)
				// 多个连续空格只保留一个
				this.fontDataList = [];
				let tempText = this.text;
				let {
					fontSize,
					letterSpacing
				} = this
				let textLen = tempText.length;
				
				
				if (this.isBold){
					this.ctx.font = `bold ${fontSize}px ${this.familyPath == 'Arial' ? 'Arial' : 'myFamily'}`
				}else{
					this.ctx.font = `${fontSize}px ${this.familyPath == 'Arial' ? 'Arial' : 'myFamily'}`
				}
				this.ctx.setTextBaseline('middle');
				this.ctx.setFillStyle(this.fontColor);
				
				
				

				// 如果绘制的文本总宽度并没有超过最大宽度，那么直接绘制
				if (this.ctx.measureText(tempText).width + textLen * letterSpacing < this.canvasWidth) {
					this.ctx.fillText(tempText, 0, fontSize);
				} else {
					let strArray = []
					let tempStr = ''
					for (let i = 0; i < textLen; i++) {
						let currStr = tempText[i]
						// 判断当前字符是否是换行符，如果是，那么新增下一行
						if ((this.ctx.measureText(tempStr + currStr).width + (tempStr.length + 1) * letterSpacing) < this.canvasWidth) {
							// 如果不是换行符且当前绘制的文本宽度加字距小于最大宽度，直接当前行字符串直接拼接
							tempStr += currStr
						} else {
							// 否则就是当前行的宽度已经达到极限，进行换行
							strArray.push(tempStr)
							tempStr = ''
							tempStr += currStr
						}
					}
					// 如果还有剩余结尾的字符串，直接就算作一行
					if (tempStr != '') {
						strArray.push(tempStr)
						tempStr = ''
					}
					// 真实行高
					let rowHeight = fontSize + this.lineHeight;
					// 总高度
					this.canvasHeight = (strArray.length + 1) * rowHeight;


					for (let i = 0; i < strArray.length; i++) {
						this.handleDrawOneLineText(strArray[i], i);
					}
					this.ctx.draw()
				}
				console.log('this.fontDataList', this.fontDataList);
			},
			handleDrawOneLineText(str, index) {
				let rowHeight = this.fontSize + this.lineHeight;

				let tempStr = ''
				for (let i = 0, len = str.length; i < len; i++) {
					// 逐字绘制，每行的y不变，单个字符的x是前面绘制文本的宽度加上每个字符的间距和
					let char = str[i];
					// 每一个字符宽度
					let gridWidth = this.ctx.measureText(char).width;

					let x = i * this.letterSpacing + (this.ctx.measureText(tempStr).width);
					
					
					this.fontDataList.push({
						char,
						x,
						y: index * (this.fontSize + this.lineHeight),
						width: gridWidth,
						height: rowHeight,
						xoffset: 0,
						yoffset: 0,
						xadvance: gridWidth,
					});
					
					//设置画笔（绘制线条）操作的线条宽度，非必须；如果不写这句，那就是默认1
					if (this.isStroke){
						this.ctx.lineWidth = this.strokeWidth;
						this.ctx.strokeStyle = this.strokeColor;
						this.ctx.strokeText(char,x, rowHeight * index + (rowHeight / 2));
					}
					if(this.isStroke && this.isHollow){
					}else{
						this.ctx.fillText(char, x, rowHeight * index + (rowHeight / 2));
					}
					
					
					
					
					

					tempStr += str[i]
				}
			},
			handleChangeText(){
				this.handleDrawText()
				setTimeout(() => {
					this.handleDrawText();
				}, 10)
			},
			handleUpdataCanvas(){
				this.handleDrawText()
				setTimeout(() => {
					this.handleDrawText();
				}, 10)
				
			},
			onDownload() {
				var _this = this;

				let imageList = this.fontDataList;
				let fileName = 'font6'
				console.error('fontSize', this.fontSize);
				uni.canvasToTempFilePath({
					canvasId: 'nnCanvas',
					success: function(res) {
						// 在H5平台下，tempFilePath 为 base64
						var arr = res.tempFilePath.split(',');
						var bytes = atob(arr[1]);
						let ab = new ArrayBuffer(bytes.length);
						let ia = new Uint8Array(ab);
						for (let i = 0; i < bytes.length; i++) {
							ia[i] = bytes.charCodeAt(i);
						}

						var blob = new Blob([ab], {
							type: 'application/octet-stream'
						});
						saveAs(blob, fileName + ".png");



						let str =
							`info size=${_this.fontSize} unicode=1 stretchH=100 smooth=1 aa=1 padding=0,0,0,0 spacing=1,1 outline=0 common lineHeight=${_this.fontSize} base=23 scaleW=${_this.fontCanvasWidth} scaleH=${_this.fontCanvasHeight} pages=1 packed=0 page id=0 file="${fileName}.png" chars count=${imageList.length}\n`;
						imageList.forEach(img => {
							str +=
								`char id=${img.char.charCodeAt(0)} x=${img.x} y=${img.y} width=${img.width} height=${img.height} xoffset=${img.xoffset} yoffset=${img.yoffset} xadvance=${img.xadvance} letter=${img.char}\n`;
						});
						let blob_font = new Blob([str], {
							type: "text/plain;charset=utf-8"
						});
						saveAs(blob_font, fileName + ".fnt");
					}
				})

			}
		}
	}
</script>

<style lang="less" scoped>
	page {
		width: 100%;
		height: 100%;
		// background-image: 
		// 	linear-gradient(45deg, #ccc 25%, transparent 0, transparent 75%, #ccc 0),
		// 	linear-gradient(45deg, #ccc 25%, transparent 0, transparent 75%, #ccc 0);
		// background-position: 0 0, 10px 10px;
		// background-size: 20px 20px;
	}
	
	.container{
		width: 100%;
		height: 100%;
	}
	.container-left{
		// flex:1;
		padding: 10px;
	}
	.container-right{
		display: flex;
		background-color: #fff;
		width: 450px;
		height:100%;
		position: fixed;
		right: 0px;
		top: 0px;
		overflow: auto;
		float: right;
	}
	.nnCanvas{
		border: 1px solid #000000;
	}

	
	
	





</style>